#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>
#include <stdexcept>

using namespace std;

// ================== 内存管理模块 ==================
class MemoryManager {
public:
    MemoryManager(int total_memory = 4096) : total_memory(total_memory) {
        free_blocks.push_back({0, total_memory});
    }

    bool allocate(int pid, int size, int& start_addr) {
        for (size_t i = 0; i < free_blocks.size(); ++i) {
            if (free_blocks[i][1] >= size) {
                start_addr = free_blocks[i][0];
                allocated[pid] = {start_addr, size};
                if (free_blocks[i][1] == size) {
                    free_blocks.erase(free_blocks.begin() + i);
                } else {
                    free_blocks[i][0] += size;
                    free_blocks[i][1] -= size;
                }
                return true;
            }
        }
        return false;
    }

    bool deallocate(int pid) {
        if (allocated.find(pid) == allocated.end()) {
            return false;
        }
        auto block = allocated[pid];
        free_blocks.push_back(block);
        allocated.erase(pid);
        return true;
    }

    void get_memory_status() const {
        cout << "总内存: " << total_memory << " KB" << endl;
        cout << "空闲分区:" << endl;
        for (const auto &block : free_blocks) {
            cout << "  " << block[0] << "-" << block[0] + block[1] - 1 << " (" << block[1] << " KB)" << endl;
        }
        cout << "已分配:" << endl;
        for (const auto &kv : allocated) {
            cout << "  PID" << kv.first << ": " << kv.second[0] << "-" << kv.second[0] + kv.second[1] - 1 
                 << " (" << kv.second[1] << " KB)" << endl;
        }
    }

private:
    int total_memory;
    vector<vector<int>> free_blocks;
    unordered_map<int, vector<int>> allocated;
};

// ================== 进程管理模块 ==================
enum class ProcessState {
    READY,
    RUNNING,
    BLOCKED,
    TERMINATED
};

class PCB {
public:
    PCB() = default;
    PCB(int pid, const string& name, int duration, int mem_size)
        : pid(pid), name(name), state(ProcessState::READY), 
          duration(duration), mem_size(mem_size), mem_start(-1) {}

    int pid;
    string name;
    ProcessState state;
    int duration;
    int mem_size;
    int mem_start;
};

class ProcessManager {
public:
    ProcessManager() : next_pid(1) {}

    int create_process(const string& name, int duration, int mem_size) {
        int pid = next_pid++;
        int start_addr;
        if (!memory.allocate(pid, mem_size, start_addr)) {
            return -1;
        }
        auto result = processes.emplace(pid, PCB(pid, name, duration, mem_size));
        result.first->second.mem_start = start_addr;
        return pid;
    }

    bool kill_process(int pid) {
        auto it = processes.find(pid);
        if (it == processes.end()) {
            return false;
        }
        memory.deallocate(pid);
        processes.erase(it);
        return true;
    }

    void list_processes() const {
        cout << "PID\tName\tState\tDuration\tMemSize\tMemAddr" << endl;
        for (const auto &kv : processes) {
            const PCB &p = kv.second;
            cout << p.pid << "\t" << p.name << "\t" 
                 << static_cast<int>(p.state) << "\t" << p.duration << "\t\t"
                 << p.mem_size << "\t" << p.mem_start << endl;
        }
    }

    MemoryManager memory;

private:
    unordered_map<int, PCB> processes;
    int next_pid;
};

// ================== 文件管理模块 ==================
class FCB {
public:
    FCB() = default;
    FCB(int fid, const string& name, int block_start)
        : fid(fid), name(name), block_start(block_start) {}

    int fid;
    string name;
    int block_start;
};

class FileManager {
public:
    FileManager(int disk_size = 10240) : disk(disk_size, 0), next_block(0) {}

    bool create_file(const string& filename, int size = 1) {
        if (files.find(filename) != files.end()) {
            return false;
        }
        if (next_block + size > disk.size()) {
            return false;
        }
        files.emplace(filename, FCB(files.size() + 1, filename, next_block));
        next_block += size;
        return true;
    }

    bool delete_file(const string& filename) {
        return files.erase(filename) > 0;
    }

    void list_file(const string& filename) const {
        auto it = files.find(filename);
        if (it == files.end()) {
            cout << "文件不存在" << endl;
            return;
        }
        const FCB &fcb = it->second;
        cout << "文件ID: " << fcb.fid << endl;
        cout << "文件名: " << fcb.name << endl;
        cout << "起始块: " << fcb.block_start << endl;
        cout << "大小: 1 块" << endl;
    }

private:
    vector<int> disk;
    unordered_map<string, FCB> files;
    int next_block;
};

// ================== 主程序 ==================
class OSController {
public:
    void handle_command(const string& cmd) {
    vector<string> parts;
    size_t start = 0, end;
    while ((end = cmd.find(' ', start)) != string::npos) {
        parts.push_back(cmd.substr(start, end - start));
        start = end + 1;
    }
    parts.push_back(cmd.substr(start));

    if (parts.empty()) return;

    try {
        if (parts[0] == "creatproc") {
            if (parts.size() < 4) {
                cout << "参数错误！格式：creatproc 进程名 运行时长 内存大小" << endl;
                return;
            }
            int pid = proc_mgr.create_process(parts[1], stoi(parts[2]), stoi(parts[3]));
            if (pid == -1) {
                cout << "进程创建失败: 内存不足" << endl;
            } else {
                cout << "进程创建成功, PID=" << pid << endl;
            }
        } 
        else if (parts[0] == "killproc") {
            if (parts.size() < 2) {
                cout << "参数错误！格式：killproc PID" << endl;
                return;
            }
            if (proc_mgr.kill_process(stoi(parts[1]))) {
                cout << "进程终止成功" << endl;
            } else {
                cout << "进程终止失败: PID不存在" << endl;
            }
        }
        else if (parts[0] == "psproc") {
            proc_mgr.list_processes();
        }
        else if (parts[0] == "mem") {
            proc_mgr.memory.get_memory_status();
        }
        else if (parts[0] == "creatfile") {
            if (parts.size() < 2) {
                cout << "参数错误！格式：creatfile 文件名" << endl;
                return;
            }
            if (file_mgr.create_file(parts[1])) {
                cout << "文件创建成功" << endl;
            } else {
                cout << "文件创建失败: 磁盘空间不足或文件已存在" << endl;
            }
        }
        else if (parts[0] == "deletefile") {
            if (parts.size() < 2) {
                cout << "参数错误！格式：deletefile 文件名" << endl;
                return;
            }
            if (file_mgr.delete_file(parts[1])) {
                cout << "文件删除成功" << endl;
            } else {
                cout << "文件删除失败: 文件不存在" << endl;
            }
        }
        else if (parts[0] == "lsfile") {
            if (parts.size() < 2) {
                cout << "参数错误！格式：lsfile 文件名" << endl;
                return;
            }
            file_mgr.list_file(parts[1]);
        }
        else if (parts[0] == "exit") {
            exit(0);
        }
        else {
            cout << "未知命令" << endl;
            cout << "支持命令：" << endl;
            cout << "  creatproc <name> <duration> <mem_size> - 创建进程" << endl;
            cout << "  killproc <pid> - 终止进程" << endl;
            cout << "  psproc - 列出所有进程" << endl;
            cout << "  mem - 显示内存状态" << endl;
            cout << "  creatfile <filename> - 创建文件" << endl;
            cout << "  deletefile <filename> - 删除文件" << endl;
            cout << "  lsfile <filename> - 显示文件信息" << endl;
            cout << "  exit - 退出程序" << endl;
        }
    } 
    catch (const invalid_argument& e) {
        cout << "参数错误: 请输入有效的数字" << endl;
    }
    catch (const exception& e) {
        cout << "错误: " << e.what() << endl;
    }
}

private:
    ProcessManager proc_mgr;
    FileManager file_mgr;
};

int main() {
    OSController os;
    cout << "=== 操作系统模拟程序 ===" << endl;
    cout << "支持命令：creatproc, killproc, psproc, mem, creatfile, deletefile, lsfile, exit" << endl;
    
    string cmd;
    while (true) {
        cout << "> ";
        getline(cin, cmd);
        if (cmd.empty()) continue;
        if (cmd == "exit") break;
        os.handle_command(cmd);
    }
    return 0;
}